<script setup>
import { ref } from 'vue';
import { MdEditor ,NormalToolbar} from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
/*const url = "ws://localhost:9090/websocket/message"*/
const url = "ws://120.27.238.159:9090/websocket/message"
let ws = new WebSocket(url);
const text = ref('')
const flag = ref(false)
function join(){
  text.value = articleStore.articleData
  ws.onopen = function (event) {
    console.log("首次发起连接")
  };
  ws.onmessage = function (event) {
    if (flag.value){
      text.value = appendToContainer(event.data)
      //console.log("响应数据:",event.data)
      return
    }
    if (event.data === "success"){
      flag.value = true
      console.log("首次连接成功:",event.data)
    }
  };
  ws.onclose = function (event) {
    console.log("已经关闭连接")
  };
}

// 初始化一个空数组作为容器
const charArray = ref([]);

// 定义一个函数用于追加字符
function appendToContainer(char) {
  charArray.value.push(char);
  return charArray.value.join('');
}
import useArticleStore from "@/store/modules/article.js"
import {listArticle,addArticleById} from "@/api/article/article.js";
import {ElMessage, ElMessageBox} from "element-plus";
import axios from "axios";
import {getToken} from "@/utils/auth.js";
const articleStore = useArticleStore()


const userMsg = ref()
function userSend(){
  if (ws) {
    console.log("发送的内容为:",userMsg.value)
    ws.send(userMsg.value);
    open.value = false
    charArray.value=[]
    text.value = null
  } else {
    alert("未连接到服务器");
  }
}

function exit() {
  if (ws) {
    ws.close();
    ws = null;
  }
}

const toolbars = [
  'bold',
  'underline',
  'italic',
  '-',
  'title',
  'strikeThrough',
  'sub',
  'sup',
  'quote',
  'unorderedList',
  'orderedList',
  'task',
  '-',
  'codeRow',
  'code',
  'link',
  'image',
  'table',
  'mermaid',
  'katex',
  '-',
  'revoke',
  'next',
  'save',
  0,
  1,
  '=',
  'pageFullscreen',
  'fullscreen',
  'preview',
  'previewOnly',
  'htmlPreview',
  'catalog',
/*  'github',*/

];

const handler = () => {
  open.value = true
  userMsg.value = null
};
const open = ref(false)

function onSave (v, h){
  articleStore.saveArticleData(v)
}
//选择文章
function handlerArticle(){
  getArticleList()
  dialogTableVisible.value = true
}
//弹框js
const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    name: null,
    isStart: null,
  },
  rules: {
  },
  articleQueryParams: {
    pageNum: 1,
    pageSize: 2,
    title:null,
    sendTime:null,
    status:null,
    labelId:null,
  },

});
const dialogTableVisible = ref(false)
const { queryParams, form, rules,articleQueryParams } = toRefs(data);
const showSearch = ref(true);
/** 文章搜索按钮操作 */
function articleHandleQuery() {
  articleQueryParams.value.pageNum = 1;
  getArticleList();
}
const gridData = ref([])
const articleTotal = ref(0);
/** 查询文章列表 */
function getArticleList() {
  listArticle(articleQueryParams.value).then(response => {
    gridData.value = response.rows;
    articleTotal.value = response.total
  });
}
const { proxy } = getCurrentInstance();
const { article_status } = proxy.useDict("article_status");
/** 重置标签下文章按钮操作 */
function articleResetQuery() {
  proxy.resetForm("articleQueryRef");
  articleHandleQuery();
}
const background = ref(false)
const disabled = ref(false)
/**分页查询*/
const handleSizeChange = (val) => {
  articleQueryParams.pageSize = val
  getArticleList()
  console.log(`${val} items per page`)
}
const handleCurrentChange = (val) => {
  articleQueryParams.pageNum = val
  getArticleList()
  console.log(`current page: ${val}`)
}
function handlePublish(item){
  console.log("item",item)
  ElMessageBox.confirm(
      '将内容保存到标题为 “'+item.title+'” 的文章？',
      'Warning',
      {
        /*confirmButtonText: 'OK',*/
        /*cancelButtonText: 'Cancel',*/
        type: 'warning',
       /* icon: "CircleCloseFilled",*/
        center: true,
      }
  )
      .then(() => {

        articleStore.saveArticleData(text.value)
        ElMessage({
          type: 'success',
          message: '保存成功',
        })

        const parm = {
          id:item.id,
          content:text.value
        }
        addArticleById(parm)
        dialogTableVisible.value = false
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '取消操作',
        })
      })

}
const baseUrl = "http://120.27.238.159" + import.meta.env.VITE_APP_BASE_API
//const baseUrl = "http://localhost" + import.meta.env.VITE_APP_BASE_API
//帮我写一篇nginx基础知识的文章，要求1000字左右，并且要有代码演示
const onUploadImg = async (files, callback) => {
  const res = await Promise.all(
      files.map((file) => {
        return new Promise((rev, rej) => {
          const form = new FormData();
          form.append('file', file);

          axios
              .post(import.meta.env.VITE_APP_BASE_API+'/common/upload', form, {
                headers: {
                  'Content-Type': 'multipart/form-data',
                  'authorization':'Bearer ' + getToken()
                },
              })
              .then((res) => {

                rev(res)
              })
              .catch((error) => rej(error));
        });
      })
  );

  callback(res.map((item) => {
    return baseUrl + item.data.fileName
  }));
};


join()
</script>

<template>
  <div>
    <MdEditor style="min-height: 90vh"
              @onSave="onSave"
              v-model="text"
              @onUploadImg="onUploadImg"
              :toolbars="toolbars" >
      <template #defToolbars>
        <NormalToolbar title="文章生成" @onClick="handler">
          <template #trigger>
            <svg t="1741461057324" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3694" width="16" height="16"><path d="M826.368 325.632c0-7.168 2.048-10.24 10.24-10.24h123.904c7.168 0 10.24 2.048 10.24 10.24v621.568c0 7.168-2.048 10.24-10.24 10.24h-122.88c-8.192 0-10.24-4.096-10.24-10.24l-1.024-621.568z m-8.192-178.176c0-50.176 35.84-79.872 79.872-79.872 48.128 0 79.872 32.768 79.872 79.872 0 52.224-33.792 79.872-81.92 79.872-46.08 1.024-77.824-27.648-77.824-79.872zM462.848 584.704C441.344 497.664 389.12 307.2 368.64 215.04h-2.048c-16.384 92.16-58.368 247.808-92.16 369.664h188.416zM243.712 712.704l-62.464 236.544c-2.048 7.168-4.096 8.192-12.288 8.192H54.272c-8.192 0-10.24-2.048-8.192-12.288l224.256-783.36c4.096-13.312 7.168-26.624 8.192-65.536 0-6.144 2.048-8.192 7.168-8.192H450.56c6.144 0 8.192 2.048 10.24 8.192l250.88 849.92c2.048 7.168 0 10.24-7.168 10.24H573.44c-7.168 0-10.24-2.048-12.288-7.168l-65.536-236.544c1.024 1.024-251.904 0-251.904 0z" fill="#FF7F18" p-id="3695"></path></svg>
          </template>
        </NormalToolbar>

        <NormalToolbar title="选择文章" @onClick="handlerArticle">
          <template #trigger>
            <svg t="1741533370323" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3951" width="18" height="18"><path d="M511.984 64C264.976 64 64 264.96 64 512.016 64 759.024 264.976 960 511.984 960 759.056 960 960 759.024 960 512.016 960 264.944 759.024 64 511.984 64z" fill="#FFBD27" p-id="3952"></path><path d="M456.624 685.696a36.8 36.8 0 0 1-26.112-10.848l-147.712-148.32c-14.4-14.464-14.4-37.968 0-52.432a36.816 36.816 0 0 1 52.224 0l121.6 122.08 232.352-233.28a36.752 36.752 0 0 1 52.224 0c14.4 14.464 14.4 37.92 0 52.4L482.736 674.848a36.864 36.864 0 0 1-26.112 10.848z" fill="#333333" p-id="3953"></path></svg>
          </template>
        </NormalToolbar>
      </template>
    </MdEditor>


    <!--ai输入框-->
    <el-drawer
        v-model="open"
        :direction="'ttb'"
        :show-close="false"
        style="align-items: center;width: 100%; justify-content: center;"
        :size="280"
    >
      <div style="display: flex;"> <!-- 添加这一行，将内部容器设置为Flex布局 -->
        <div class="brutalist-container">
          <input placeholder="请输入关于文章的类型，知识点等内容"
                 class="brutalist-input smooth-type"
                 type="text"
                 v-model="userMsg"
                 @keyup.enter="userSend()"
          />
          <label class="brutalist-label">please input</label>
        </div>
        <div>
          <button class="btn" @click="userSend()">Reply</button>
        </div>
      </div>
    </el-drawer>

    <!--查看文章按钮-->
    <el-dialog v-model="dialogTableVisible" title="文章"  center width="950">
      <div>
        <el-form :model="articleQueryParams"   ref="articleQueryRef" :inline="true" v-show="showSearch" >
          <el-form-item label="文章标题" prop="title">
            <el-input
                v-model="articleQueryParams.title"
                placeholder="请输入文章标题"
                @keyup.enter="articleHandleQuery"
            />
          </el-form-item>

          <el-form-item label="文章状态" prop="status">
            <el-select v-model="articleQueryParams.status"  clearable style="width: 196px">
              <el-option
                  v-for="dict in article_status"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
              />
            </el-select>
          </el-form-item>



          <el-form-item>
            <el-button type="primary" icon="Search" @click="articleHandleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="articleResetQuery">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <el-table :data="gridData">
        <el-table-column prop="title" label="文章"  align="center" />
        <el-table-column prop="author" label="作者"  align="center" />
        <el-table-column  prop="sendTime" label="发布时间" align="center" >
          <template #default="scope">
            <span style="color: red" v-if="scope.row.sendTime == null">待发布</span>
          </template>
        </el-table-column>

        <el-table-column label="操作" align="center" >
          <template #default="scope">
            <el-button link type="primary" icon="Pointer" @click="handlePublish(scope.row)"  >保存</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
          class="my-pagination"
          v-model:current-page="articleQueryParams.pageNum"
          v-model:page-size="articleQueryParams.pageSize"
          :page-sizes="[2, 4, 6, 8]"
          size="default"
          :disabled="disabled"
          :background="background"
          layout="total, sizes, prev, pager, next, jumper"
          :total="articleTotal"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </el-dialog>

  </div>

</template>

<style scoped lang="scss">


.brutalist-container {
  position: relative;
  width: 70%;
  margin-top: 20px;
  font-family: monospace;
}

.brutalist-input {
  width: 100%;
  padding: 15px;
  font-size: 18px;
  font-weight: bold;
  color: #000;
  background-color: #fff;
  border: 4px solid #000;
  position: relative;
  overflow: hidden;
  border-radius: 0;
  outline: none;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  box-shadow: 5px 5px 0 #000, 10px 10px 0 #4a90e2;
}

@keyframes glitch {
  0% {
    transform: translate(0);
  }

  20% {
    transform: translate(-2px, 2px);
  }

  40% {
    transform: translate(-2px, -2px);
  }

  60% {
    transform: translate(2px, 2px);
  }

  80% {
    transform: translate(2px, -2px);
  }

  100% {
    transform: translate(0);
  }
}

.brutalist-input:focus {
  animation: focus-pulse 4s cubic-bezier(0.25, 0.8, 0.25, 1) infinite,
  glitch 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) infinite;
}

.brutalist-input:focus::after {
  content: "";
  position: absolute;
  top: -2px;
  left: -2px;
  right: -2px;
  bottom: -2px;
  background: white;
  z-index: -1;
}

.brutalist-input:focus::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: black;
  z-index: -2;
  clip-path: inset(0 100% 0 0);
  animation: glitch-slice 4s steps(2, end) infinite;
}

@keyframes glitch-slice {
  0% {
    clip-path: inset(0 100% 0 0);
  }

  10% {
    clip-path: inset(0 5% 0 0);
  }

  20% {
    clip-path: inset(0 80% 0 0);
  }

  30% {
    clip-path: inset(0 10% 0 0);
  }

  40% {
    clip-path: inset(0 50% 0 0);
  }

  50% {
    clip-path: inset(0 30% 0 0);
  }

  60% {
    clip-path: inset(0 70% 0 0);
  }

  70% {
    clip-path: inset(0 15% 0 0);
  }

  80% {
    clip-path: inset(0 90% 0 0);
  }

  90% {
    clip-path: inset(0 5% 0 0);
  }

  100% {
    clip-path: inset(0 100% 0 0);
  }
}

.brutalist-label {
  position: absolute;
  left: -3px;
  top: -35px;
  font-size: 14px;
  font-weight: bold;
  color: #fff;
  background-color: #000;
  padding: 5px 10px;
  transform: rotate(-1deg);
  z-index: 1;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.brutalist-input:focus+.brutalist-label {
  transform: rotate(0deg) scale(1.05);
  background-color: #4a90e2;
}

.smooth-type {
  position: relative;
  overflow: hidden;
}

.smooth-type::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: linear-gradient(90deg, #fff 0%, rgba(255, 255, 255, 0) 100%);
  z-index: 1;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.smooth-type:focus::before {
  opacity: 1;
  animation: type-gradient 2s linear infinite;
}

@keyframes type-gradient {
  0% {
    background-position: 300px 0;
  }

  100% {
    background-position: 0 0;
  }
}

.brutalist-input::placeholder {
  color: #888;
  transition: color 0.3s ease;
}

.brutalist-input:focus::placeholder {
  color: transparent;
}

.brutalist-input:focus {
  animation: focus-pulse 4s cubic-bezier(0.25, 0.8, 0.25, 1) infinite;
}

@keyframes focus-pulse {

  0%,
  100% {
    border-color: #000;
  }

  50% {
    border-color: #4a90e2;
  }
}


.btn {
  width: 170px;
  height: 60px;
  margin-top: 25px;
  margin-left: 50%;
  font-size: 18px;
  background: #ffb6b9;
  border: none;
  border-radius: 50px;
  color: #000;
  outline: none;
  cursor: pointer;
  transition: all 0.4s;
}

.btn:hover {
  box-shadow: inset 0 0 0 4px #ef476f,
  inset 0 0 0 8px #ffd166,
  inset 0 0 0 12px #06d6a0,
  inset 0 0 0 16px #118ab2;
  background: #073b4c;
  color: #fff;
}

:deep(.el-drawer__body){
  width: 75%;
}


</style>